<?php
ini_set('display_erros',true);
error_reporting(E_ALL);


class PXFRecordSet
{
	public function __toString()
	{
		return get_class($this);
	}
}

/**
* PXFRelationFactory
*
*/
class PXFRelationFactory
{
	public static function getInstance($record,$relation,$description,$args = array())
	{
		$table = array_key_exists('table',$description) ? $description['table'] : $relation;
		switch($description['type'])
		{	
			case 'm_o':
				return new PXFRelationManyToOne($record,$relation,$table,$description,$args);
				break;
			case 'o_m':
				return new PXFRelationOneToMany($record,$relation,$table,$description,$args);
				break;
			case 'o_o':
				return new PXFRelationOneToMany($record,$relation,$table,$description,$args);
				break;
			case 'm_m':
				return new PXFRelationManyToMany($record,$relation,$table,$description,$args);
				break;
		}
	}
}

/**
* PXFRelationManyToOne 
*
*/
class PXFRelationManyToOne extends PXFRecord
{
	private $relation_id;

	public function __construct($record,$relation,$table,$description)
	{
		$model = PXFModel::getModel($table);
		$value = $description['fkey'];
		$tmp = $model->find($record->$value); 
		$this->model = $model;
		$this->fields= $tmp->fields;
	}

	public function load()
	{
		return $this;
	}
}

/**
* PXFRelationOneToOne 
*
*/
class PXFRelationOneToOne extends PXFRecord
{
	public function __construct($model,$relation,$table,$description)
	{
		$model = PXFModel::getModel($table);
		$value = $description['fkey'];
		$tmp = $model->find($record->$value); 
		$this->model = $model;
		$this->attrs = $tmp->attrs;
	}
}

/**
* PXFRelationOneToMany 
*
*/
class PXFRelationOneToMany extends PXFRecordSet
{
	private $record = null;
	private $relation = null;

	public function __construct($record,$relation,$table,$description)
	{
		$this->record = $record;
		$this->table = $table;
		$this->relation = $relation;
	}

	public function load($args = array())
	{
		$model = PXFModel::getModel($this->table);
		$value = $this->record->model->relations[$this->relation]['fkey'];

		if(array_key_exists('condition',$args))
		{
			$args['condition']->add(PXFCondition::opAND($value,$this->record->id));
		}
		else
		{
			$args['condition'] = new PXFCondition($value,$this->record->id);
 		}

		$query = PXFSQLBuilder::select($model,$model->getFields());
		$query .= PXFSQLBuilder::parseArgs($args);
		return $model->findByQuery($query); 
	}

	public function own($record)
	{
		$db = PXFDataBase::getInstance();
		$fields = array(sprintf('%s_id',$this->record->model->__toString()) => $this->record->id);
		$conditions = array('condition' => new PXFCondition('id',$record->id));
		$query = PXFSQLBuilder::update($record,$fields);
		$query = PXFSQLBuilder::whereByConditions($conditions);
		$db->update($query); 
	}

	public function count($args = array())
	{
		if(array_key_exists('condition',$args))
		{
			$args['condition']->add(PXFCondition::opAND(sprintf('%s_id',$this->record->model->__toString()),$this->record->id));
		}
		else
		{
			$args['condition'] = new PXFCondition(sprintf('%s_id',$this->record->model->__toString()),$this->record->id);
 		}

		$db = PXFDataBase::getInstance();
		$model = PXFModel::getModel($this->table);
		$query = PXFSQLBuilder::count($model);
		$query .= PXFSQLBuilder::parseArgs($args);
		$result = $db->select($query); 
		$count = $db->fetch($result);
		return $count['total'];
	}
}

/**
* PXFRelationManyToMany 
*
*/
class PXFRelationManyToMany extends PXFRecordSet
{
	private $record = null;
	private $relation = null;

	public function __construct($record,$relation,$table,$description,$args = array())
	{
		$this->record = $record;
		$this->table = $table;
		$this->relation = $relation;
	}

	public function load($args = array())
	{
		$model = PXFModel::getModel($this->table);
		$query  = PXFSQLBuilder::select($model,$model->getFields());
		$query .= PXFSQLBuilder::innerJoin($model->__toString(),$this->record->model->__toString(),$this->record->id,$args);
		return $model->findByQuery($query); 
	}

	public function add(PXFRecord $record)
	{	
		$db = PXFDataBase::getInstance();

		$tables = PXFSQLBuilder::joinTables($this->record->__toString(),$record->__toString());
		$fields = array(
				sprintf('%s_id',$record) => $record->id,
				sprintf('%s_id',$this->record) => $this->record->id,
				);
		$query = PXFSQLBuilder::replace($tables,$fields);
		$db->insert($query); 
	}

	public function remove(PXFRecord $record)
	{
		$condition = new PXFCondition(sprintf('%s_id',$record->__toString()),$record->id);
		$condition->add(PXFCondition::opAND(sprintf('%s_id',$this->record->__toString()),$this->record->id));

		$db = PXFDataBase::getInstance();
		$tables = PXFSQLBuilder::joinTables($this->record->__toString(),$record->__toString());
		$query  = PXFSQLBuilder::delete($tables);
		$query .= PXFSQLBuilder::whereByConditions($condition);
		$db->delete($query); 
	}

	public function count($args = array())
	{
		$db = PXFDataBase::getInstance();
		$model = PXFModel::getModel($this->table);
		$query = PXFSQLBuilder::count($model);
		$query .= PXFSQLBuilder::innerJoin($model,$this->record->model,$this->record->id,$args);
		$result = $db->select($query); 
		$count = $db->fetch($result);
		return $count['total'];
	}
}
?>
